using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GameAOT;
using System;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class UIBattleInput : UIEntityWindow
    {
        /// <summary>
        /// 静态配置
        /// </summary>
        private static UICreateConfig _createConfig = new()
        {
            prefabName = nameof(UIBattleInput),
            parentPath = "Battle",
            layer = EUILayer.Normal,
        };

        public override IUICreateConfig createConfig => _createConfig;

        protected UIB_UIBattleInput ui { get; set; }

        private Action<Vector2> onJoystickMove;
        private Action onJoystickUp;

        private Action<int, Vector2> onSkillJoystickMove;
        private Action<int, bool> onSkillJoystickUp;

        private Action onStanBy;

        private SkillViewComponent _curView;

        private bool cancel;

        #region Template Generate,don't modify

        protected partial class UIB_UIBattleInput
        {
            #region ObjectBinding Generate
            public IQIGame.Onigao.GamePlay.Joystick joystick { protected set; get; }
            public IQIGame.Onigao.GamePlay.SkillJoystick slot2 { protected set; get; }
            public UnityEngine.RectTransform cancelArea { protected set; get; }
            public IQIGame.Onigao.GamePlay.SkillJoystick slot1 { protected set; get; }
            public IQIGame.Onigao.GamePlay.SkillJoystick slot3 { protected set; get; }
            public IQIGame.Onigao.GamePlay.SkillJoystick slot4 { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton stanBy { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton auto { protected set; get; }
            public UnityEngine.GameObject skillBtn { protected set; get; }
            public UnityEngine.GameObject panel { protected set; get; }
            public IQIGame.Onigao.GamePlay.SkillJoystick slotPet { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<IQIGame.Onigao.GamePlay.Joystick>("joystick", out var __tbv0);
                this.joystick = __tbv0;
                __binding.TryGetVariableValue<IQIGame.Onigao.GamePlay.SkillJoystick>("slot2", out var __tbv1);
                this.slot2 = __tbv1;
                __binding.TryGetVariableValue<UnityEngine.RectTransform>("cancelArea", out var __tbv2);
                this.cancelArea = __tbv2;
                __binding.TryGetVariableValue<IQIGame.Onigao.GamePlay.SkillJoystick>("slot1", out var __tbv3);
                this.slot1 = __tbv3;
                __binding.TryGetVariableValue<IQIGame.Onigao.GamePlay.SkillJoystick>("slot3", out var __tbv4);
                this.slot3 = __tbv4;
                __binding.TryGetVariableValue<IQIGame.Onigao.GamePlay.SkillJoystick>("slot4", out var __tbv5);
                this.slot4 = __tbv5;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("stanBy", out var __tbv6);
                this.stanBy = __tbv6;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("auto", out var __tbv7);
                this.auto = __tbv7;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("skillBtn", out var __tbv8);
                this.skillBtn = __tbv8;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("panel", out var __tbv9);
                this.panel = __tbv9;
                __binding.TryGetVariableValue<IQIGame.Onigao.GamePlay.SkillJoystick>("slotPet", out var __tbv10);
                this.slotPet = __tbv10;
            }
            #endregion ObjectBinding Generate
        }

        #endregion Template Generate,don't modify

        /// <summary>
        /// 可以自定义修改的
        /// </summary>
        protected partial class UIB_UIBattleInput
        {
            public virtual void StartBinding(GameObject __go)
            {
                var binding = __go.GetComponent<ObjectBinding>();
                if (binding != null)
                {
                    this.InitBinding(binding);
                }
            }
        }


        protected override void OnInit()
        {
            this.ui.joystick.onTouchMove += OnJoystickMove;
            this.ui.joystick.onTouchUp += OnJoystickUp;

            this.ui.slot1.onTouchMove += (x) => this.OnSkillSlotMove(0, x);
            this.ui.slot1.onTouchUp += () => this.OnSkillSlotUp(0);

            this.ui.slot2.onTouchMove += (x) => this.OnSkillSlotMove(1, x);
            this.ui.slot2.onTouchUp += () => this.OnSkillSlotUp(1);

            this.ui.slot3.onTouchMove += (x) => this.OnSkillSlotMove(2, x);
            this.ui.slot3.onTouchUp += () => this.OnSkillSlotUp(2);

            this.ui.slot4.onTouchMove += (x) => this.OnSkillSlotMove(3, x);
            this.ui.slot4.onTouchUp += () => this.OnSkillSlotUp(3);

            this.ui.slotPet.onTouchMove += (x) => this.OnSkillSlotMove(4, x);
            this.ui.slotPet.onTouchUp += () => this.OnSkillSlotUp(4);

            this.ui.stanBy.AddClickEvent(this.OnStanBy);

            this.ui.auto.AddClickEvent(this.OnAutoClicked);
        }

        protected override void BeforeInit()
        {
            ui = new UIB_UIBattleInput();
            ui.StartBinding(gameObject);
        }

        protected override void OnShow(UIBaseData data)
        {

        }

        protected override void OnHide()
        {

        }

        protected override void OnDispose()
        {
            this.onStanBy = null;
            this.onJoystickMove = null;
            this.onJoystickUp = null;
            this.onSkillJoystickMove = null;
            this.onSkillJoystickUp = null;
        }

        public void ShowPanel()
        {
            this.ui.panel.SetActive(true);
        }

        public void HidePanel()
        {
            this.ui.panel.SetActive(false);
        }

        private void OnJoystickMove(JoystickData rInput)
        {
            if (this.onJoystickMove != null)
            {
                this.onJoystickMove.Invoke(rInput.direction.normalized * rInput.power);
            }
        }

        private void OnJoystickUp()
        {
            this.onJoystickUp?.Invoke();
        }


        private void OnSkillSlotMove(int nIndex, JoystickData rInput)
        {
            if (this._curView == null || BattleConst.SkillCastNum <= nIndex)
            {
                return;
            }

            var nSkillID = this._curView.skills[nIndex];
            onSkillJoystickMove?.Invoke(nSkillID, rInput.direction.normalized * rInput.power);

            this.cancel = RectTransformUtility.RectangleContainsScreenPoint(ui.cancelArea, Input.mousePosition, ManagerCenter.UI.UICamera);
        }

        private void OnSkillSlotUp(int nIndex)
        {
            if (this._curView == null || BattleConst.SkillCastNum <= nIndex)
            {
                return;
            }

            var nSkillID = this._curView.skills[nIndex];
            onSkillJoystickUp?.Invoke(nSkillID, this.cancel);

            // this.skillIndex = -1;
        }

        private void OnStanBy()
        {
            this.onStanBy?.Invoke();
        }

        private void OnAutoClicked()
        {
            this.ChangeAutoBattle().Forget();
        }

        private async UniTaskVoid ChangeAutoBattle()
        {
            var bCurAuto = BattleManager.Instance.ctrl.data.autoBattle;
            await BattleManager.Instance.AutoBattle(!bCurAuto);
        }

        public void AddJoystickListener(Action<Vector2> onTouchMove, Action onTouchUp)
        {
            this.onJoystickMove += onTouchMove;
            this.onJoystickUp += onTouchUp;
        }

        public void AddSkillSlotListener(Action<int, Vector2> onSkillMove, Action<int, bool> onSkillUp)
        {
            this.onSkillJoystickMove += onSkillMove;
            this.onSkillJoystickUp += onSkillUp;
        }

        public void AddStanBy(Action onStanBy)
        {
            this.onStanBy += onStanBy;
        }

        // 刷新技能释放图标与对应的技能
        public void RefreshSkillBtn(SkillViewComponent rComp)
        {
            this._curView = rComp;

            this.ui.slot1.SetSkillIcon(this.GetSkillSprite(this._curView.skills[0]), rComp.SkillCanCast(this._curView.skills[0], out var nCd1), nCd1);
            this.ui.slot2.SetSkillIcon(this.GetSkillSprite(this._curView.skills[1]), rComp.SkillCanCast(this._curView.skills[1], out var nCd2), nCd2);
            this.ui.slot3.SetSkillIcon(this.GetSkillSprite(this._curView.skills[2]), rComp.SkillCanCast(this._curView.skills[2], out var nCd3), nCd3);

            // 大招按钮
            var nBigSkill = this._curView.skills[3];
            if (nBigSkill > 0)
            {
                var nCost = this._curView.SkillSpCost(nBigSkill);
                var rAttrComp = rComp.unit.GetComponent<AttributeViewComponent>(ETComponentType.AttributeViewComponent);
                var nCurSp = rAttrComp.Get(EAttributeType.SP);
                var fSpRate = Mathf.Clamp((float)nCurSp / nCost, 0, 1);
                this.ui.slot4.SetSetSkillIconWithSp(
                    this.GetSkillSprite(nBigSkill), rComp.SkillCanCast(this._curView.skills[3], out var nCd4), nCd4,
                    fSpRate, nCurSp);
            }
            // 宠物技能
            this.ui.slotPet.SetSkillIcon(this.GetSkillSprite(this._curView.skills[4]), rComp.SkillCanCast(this._curView.skills[4], out var nCd5), nCd5);
        }


        private Sprite GetSkillSprite(int skillID)
        {
            if (skillID == 0)
            {
                return null;
            }
            var rTab = TableCenter.skill.Get(skillID);
            var rIcon = rTab.Icon;
            if (!string.IsNullOrEmpty(rIcon))
            {
                var rPath = rTab.Icon_fullPath;
                var rSprite = this.resLoader.LoadABAsset<Sprite>(rPath);
                return rSprite;
            }
            return null;
        }
    }
}